/*
 * File      : board.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-07-24     Tanek        the first version
 */
#include <rthw.h>
#include <rtthread.h>
#include "board.h"

#if 0
/* 直接使用固件库函数，这部分注释掉==========================*//*{{{*/
#define _SCB_BASE       (0xE000E010UL)
#define _SYSTICK_CTRL   (*(rt_uint32_t *)(_SCB_BASE + 0x0))
#define _SYSTICK_LOAD   (*(rt_uint32_t *)(_SCB_BASE + 0x4))
#define _SYSTICK_VAL    (*(rt_uint32_t *)(_SCB_BASE + 0x8))
#define _SYSTICK_CALIB  (*(rt_uint32_t *)(_SCB_BASE + 0xC))
#define _SYSTICK_PRI    (*(rt_uint8_t  *)(0xE000ED23UL))

// Updates the variable SystemCoreClock and must be called
// whenever the core clock is changed during program execution.
extern void SystemCoreClockUpdate(void);

// Holds the system core clock, which is the system clock
// frequency supplied to the SysTick timer and the processor
// core clock.
extern uint32_t SystemCoreClock;

static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
	if ((ticks - 1) > 0xFFFFFF) {
		return 1;
	}

	_SYSTICK_LOAD = ticks - 1;
	_SYSTICK_PRI  = 0xFF;
	_SYSTICK_VAL  = 0;
	_SYSTICK_CTRL = 0x07;

	return 0;
}/*}}}*/
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
#define RT_HEAP_SIZE    1024
static uint32_t rt_heap[RT_HEAP_SIZE];	// heap default size: 4K(1024 * 4)
RT_WEAK void *rt_heap_begin_get(void)
{
	return rt_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
	return rt_heap + RT_HEAP_SIZE;
}
#endif

/**
 * This function will initial your board.
 */
void rt_hw_board_init()
{
	/* SysTick 初始化 */
	SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分 2 组

	/* 硬件 BSP 初始化统统放在这里，比如 LED，串口，LCD 等 */
	USART1_Init(115200); //初始化串口
	LED_Init();          //初始化LED
	KEY_Init();          //初始化key
	BEEP_Init();         //初始化beep

	/* Tag: xuke modified on 2024/01/20 for fixing M#可以在这里做硬件测试，此时为裸机状态 */
	/*LED1 = 0;*/
	/*while (1);*/

	/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
	rt_components_board_init();
#endif

#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
	rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
	rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

void SysTick_Handler(void)
{
	/* enter interrupt */
	rt_interrupt_enter();

	rt_tick_increase();

	/* leave interrupt */
	rt_interrupt_leave();
}

/*
 *串口重映射 - rt_kprintf();
 */
void rt_hw_console_output(const char *str)
{
	/* 进入临界段 */
	rt_enter_critical();

	/* 直到字符串结束 */
	while (*str!='\0') {
		if (*str=='\n') {
			USART1->DR = (rt_uint8_t) '\r';
			while((USART1->SR&0X40) == 0);
		}
		USART1->DR = *str++;
		while ((USART1->SR&0X40) == 0);
	}

	/* 退出临界段 */
	rt_exit_critical();
}

